package gappengko;

import java.util.HashMap;
import java.util.Map;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Text;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/** An abstraction on top of the Google Java Datastore.
 * 
 * The query model is simpler: it takes either a map<String,String> or a string in JSON
 * format {"name":"joe","date","june"}.
 * All conditions must be satisfied.
 */
public class JsonSimpleDatastore {
  
  private SimpleDatastore _simpleDatastore;
  
  /** Utility method to discuss with SimpleDatastore */
  private Map<String,String> jsonObject2Map(JsonObject obj) {
    Map<String, String> m = new HashMap<String, String>();
    for (Map.Entry<String,JsonElement> entry : obj.entrySet()) {
      m.put(entry.getKey(), entry.getValue().getAsString());
    }
    return m;
  }

  public JsonSimpleDatastore(String kind) {
    _simpleDatastore = new SimpleDatastore(kind);
  }
  
  /** Adds an Entity in the Datastore based on the request parameters.
   * Parameters are obtained with req.getParameter, hence supports both POST and GET parameters
   */
  public JsonObject createEntity(Map<String, String> m) throws Exception {
    return entityToJsonObject(_simpleDatastore.createEntity(m));
  }
  
	 /** Adds an Entity in the Datastore corresponding to the json representation */
	 public JsonObject createEntity(String json) throws Exception {
	   JsonObject obj = new JsonParser().parse(json).getAsJsonObject();
	   return createEntity(obj);
	 }

   /** Adds an Entity in the Datastore corresponding to the json representation */
   public JsonObject createEntity(JsonObject obj) throws Exception {
     return createEntity(jsonObject2Map(obj));     
   }

	/** transforms an Entity (Google) to a JSON object (org.json) */
	public JsonObject entityToJsonObject(Entity e) throws Exception {
	  JsonObject jsonObj;
		jsonObj = new JsonObject();
		for (String prop : e.getProperties().keySet()) {
			Object val = e.getProperty(prop);
			if (val instanceof Text) {
			    jsonObj.addProperty(prop, ((Text)val).getValue());}
			else {				
			    jsonObj.addProperty(prop, val.toString());}							
		}
		
    // adding the key
		jsonObj.addProperty(Constants.KEY,Long.toString(e.getKey().getId()));
		
		return jsonObj;
	}
	
	/** get a JSON string of the object obtained with key */
	public JsonObject getJSON(String key) throws Exception {		
 		return entityToJsonObject(_simpleDatastore.getEntity(key));
	}

  /** Returns a list of JSONObject bas on the parameters in the request */
  public JsonArray search(JsonObject query) throws Exception {
    return search(jsonObject2Map(query));
  }
  
  /** Returns a list of JSONObject bas on the parameters in the request */
	public JsonArray search(Map<String, String> query) throws Exception {
	  JsonArray result = new JsonArray();
	  for (Entity e : _simpleDatastore.search(query)) {
	    result.add(entityToJsonObject(e));
	  }
	  return result;
	}

	
}
